package com.myebills.ebpsfrontend.cust.controller;

import com.checkfree.isolutions.customer.persist.AccountHomeImpl;
import com.checkfree.isolutions.customer.persist.UserHomeImpl;
import com.checkfree.isolutions.persist.PersistServer;
import com.checkfree.isolutions.statement.persist.StatementHomeImpl;
import com.checkfree.isolutions.utility.CFiError;
import com.ibm.logging.ILogger;
import com.ibm.logging.IRecordType;
import java.io.IOException;
import java.rmi.RemoteException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Intance of Strategy (GOF) pattern.
 * Override doRequest() to define response to either GET or POST HTTP request.
 */
public abstract class EbppxServlet extends HttpServlet
{

    /**
     * These values are loaded by the <code>init</code> method,
     * for future use by each request/response thread.
     * Make sure to wrap ALL accesses to these values in a
     * <code>synchronized (this) { ... }</code> block
     * (or use the synchronized <code>getXxx()</code> accessors).
     */
    private transient String _errorPage;
    private transient String _cipherAlgorithm;
    private transient String _cipherKey;
    private transient boolean _sessionIntegrity;

    /**
     * Provide thread-safe instance variable value access.
     */
    protected synchronized String getErrorPage() {
        return _errorPage;
    }

    /**
     * Provide thread-safe instance variable value access.
     */
    protected synchronized String getCipherAlgorithm() {
        return _cipherAlgorithm;
    }

    /**
     * Provide thread-safe instance variable value access.
     */
    protected synchronized String getCipherKey() {
        return _cipherKey;
    }

    /**
     * Provide thread-safe instance variable value access.
     */
    protected synchronized boolean getSessionIntegrity() {
        return _sessionIntegrity;
    }

    /**
     * Standard method of javax.servlet.http.HttpServlet;
     * initializes logging and loads URL encryption settings.
     *
     * @param   config the servlet configuration provided by the
     *          servlet engine.
     */
    public void init(ServletConfig config) throws ServletException {
        // NOTE: The servlet engine should already be calling this
        // method inside a <code>synchronized (this) { ... }</code> block,
        // so we do not need additional synchronization for servlet
        // instance variables.

        super.init(config);

        final String fName = "init";

        // Pre-load various context parameters.
        _errorPage = getContextInitParameter(
                EbppxConstants.URL_ERROR_PAGE_PARAM,
                ""
                );

        _sessionIntegrity = EbppxUtil.boolFromString(
                getContextInitParameter(
                    EbppxUrlManager.PARAM_SESSION_INTEGRITY,
                    "false"
                    )
                );

        _cipherAlgorithm = getContextInitParameter(
                EbppxUrlManager.PARAM_CIPHER_ALGORITHM,
                ""
                );
        if ((_cipherAlgorithm.length() == 0) ||
                (_cipherAlgorithm.equalsIgnoreCase(EbppxUrlManager.NULL_CIPHER_ALGORITHM))) {
            // Use plain-text URL's.
            _cipherAlgorithm = "";
            _cipherKey = "";
        } else {
            // Encrypt URL's, so we need the key.
            _cipherKey = getContextInitParameter(
                    EbppxUrlManager.PARAM_CIPHER_KEY,
                    ""
                    );
        }
    }

    /**
     * Standard method of javax.servlet.http.HttpServlet;
     * ends logging and tracing.
     */
    public void destroy() {
        EbppxLogger.quitLogging(this);
    }

    /**
     * Standard method of javax.servlet.http.HttpServlet
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     */
    public final void doPost(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws IOException, ServletException {
        try {
            createLogger(req);
            ILogger trcLogger = getTraceLogger(req);

            if (trcLogger.isLogging()) {
                trcLogger.entry(IRecordType.TYPE_INFO, this, "doPost");
            }

            createUrlManager(req, res);
            doRequest(req, res);

            if (trcLogger.isLogging()) {
                trcLogger.exit(IRecordType.TYPE_INFO, this, "doPost");
            }
        } catch (Exception e) {
            handleServletException(req, res, e);
        }
    }

    /**
     * Standard method of javax.servlet.http.HttpServlet
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     */
    public final void doGet(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws IOException, ServletException {
        try {
            createLogger(req);
            ILogger trcLogger = getTraceLogger(req);

            if (trcLogger.isLogging()) {
                trcLogger.entry(IRecordType.TYPE_INFO, this, "doGet");
            }

            createUrlManager(req, res);
            doRequest(req, res);

            if (trcLogger.isLogging())
                trcLogger.exit(IRecordType.TYPE_INFO, this, "doGet");
        } catch (Exception e) {
            handleServletException(req, res, e);
        }
    }

    /**
     * Overridable method to handle an Exception that bubbles all the way back
     * to the <code>doGet</code> or <code>doPost</code> method.
     * <p>
     * The default action is to attempt to redirect to an error JSP page,
     * passing the exception text as a message.
     * If no error page has been defined,
     * re-throw the exception for handling by the servlet engine itself.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   exception the caught <code>Exception</code> to be handled.
     */
    protected void handleServletException(
        HttpServletRequest req,
        HttpServletResponse res,
        Exception exception
    ) throws IOException, ServletException {
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging()) {
            trcLogger.message(
                    IRecordType.TYPE_INFO,
                    this,
                    "handleServletException",
                    exception.toString()
                    );
        }

        String errorPage = getErrorPage();
        if ((errorPage == null) || (errorPage.length() == 0)) {
            // Simply re-throw the exception.
            throw new ServletException(
                    "No error page configured for exception: " +
                        exception.toString(),
                    exception
                    );
        }

        HttpSession session = req.getSession();
        session.setAttribute("errorMessage", exception.toString());
        forwardToUrl(req, res, errorPage);
    }

    /**
     * Instantiate an instance of the logging bean,
     * and store it as a <em>request</em> attribute for access by
     * the current thread.
     */
    protected void createLogger(
        HttpServletRequest req
    ) throws ServletException {
        EbppxLogger logger = new EbppxLogger(this);
        req.setAttribute(EbppxLogger.REQUEST_ATTRIBUTE_NAME, logger);
    }

    /**
     * Return the current thread's instance of the message logger.
     */
    protected com.ibm.logging.ILogger getMessageLogger(
        HttpServletRequest req
    ) throws ServletException {
        EbppxLogger logger = null;
        try {
            logger = (EbppxLogger) req.getAttribute(
                    EbppxLogger.REQUEST_ATTRIBUTE_NAME
                );
        } catch (ClassCastException e) {
            throw new ServletException(
                    "Could not read request attribute [" +
                        EbppxLogger.REQUEST_ATTRIBUTE_NAME +
                        "] as an EbppxLogger object reference",
                    e
                    );
        }
        return logger.getMessageLogger();
    }

    /**
     * Return the current thread's instance of the trace logger.
     */
    protected com.ibm.logging.ILogger getTraceLogger(
        HttpServletRequest req
    ) throws ServletException {
        EbppxLogger logger = null;
        try {
            logger = (EbppxLogger) req.getAttribute(
                    EbppxLogger.REQUEST_ATTRIBUTE_NAME
                    );
        } catch (ClassCastException e) {
            throw new ServletException(
                    "Could not read request attribute [" +
                        EbppxLogger.REQUEST_ATTRIBUTE_NAME +
                        "] as an EbppxLogger object reference",
                    e
                    );
        }
        return logger.getTraceLogger();
    }

    /**
     * Instantiate an instance of the URL encryption bean,
     * and store it as a <em>request</em> attribute for access by
     * the current thread.
     */
    protected void createUrlManager(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws ServletException {
        EbppxUrlManager mgr = new EbppxUrlManager(
                req,
                res,
                getCipherAlgorithm(),
                getCipherKey(),
                getSessionIntegrity()
                );
        mgr.decryptRequestParameters();

        // We need to make the urlManager available to the current thread
        // for access by servlet methods and/or Java Server Page scriptlets.
        // (We cannot store it as an instance member of
        // <code>EbppxServlet</code>,
        // as that would not be multi-threading safe.)
        req.setAttribute(EbppxUrlManager.REQUEST_ATTRIBUTE_NAME, mgr);
    }

    /**
     * Return the current thread's instance of the URL encryption bean.
     */
    protected EbppxUrlManager getUrlManager(
        HttpServletRequest req
    ) throws ServletException {
        final String fName = "getUrlManager";
        ILogger trcLogger = getTraceLogger(req);

        EbppxUrlManager mgr = null;
        try {
            mgr = (EbppxUrlManager) req.getAttribute(
                    EbppxUrlManager.REQUEST_ATTRIBUTE_NAME
                );
        } catch (ClassCastException e) {
            if (trcLogger.isLogging()) {
                trcLogger.message(
                        IRecordType.TYPE_ERROR,
                        this,
                        fName,
                        "Could not read request attribute [" +
                            EbppxUrlManager.REQUEST_ATTRIBUTE_NAME +
                            "] as an EbppxUrlManager object reference",
                            e
                        );
            }
            mgr = null;
        }
        return mgr;
    }

    /**
     * Override this method to implement logic for satisfying the HTTP request.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     */
    protected abstract void doRequest(
        HttpServletRequest req,
        HttpServletResponse res
    ) throws IOException, ServletException;

    /**
     * Obtain a servlet initialization parameter.
     *
     * @param   sName the desired parameter name.
     *
     * @param   sDefault a default value to use if the parameter is not defined.
     *
     * @return  value of servlet initialization parameter <code>sName</code>.
     *          If <code>sName</code> is not defined,
     *          returns <code>sDefault</code>.
     */
    protected final String getInitParameter(
        String sName,
        String sDefault
    ) {
        final String sValue = getInitParameter(sName);
        return (null != sValue) ? sValue : sDefault;
    }

    /**
     * Obtain a servlet initialization parameter,
     * throwing an exception if the parameter is not defined.
     *
     * @param   sName the desired parameter name.
     *
     * @return value of servlet initialization parameter <code>sName</code>.
     *
     * @exception   IllegalStateException if <code>sName</code> is not defined
     *              as a servlet initialization parameter.
     */
    protected final String getRequiredInitParameter(
        String sName
    ) throws IllegalStateException {
        final String sValue = super.getInitParameter(sName);

        if (null == sValue) {
            throw new IllegalStateException(
                    "Servlet initialization parameter ]"
                    + sName
                    + "] is undefined"
                    );
        }

        return sValue;
    }

    /**
     * Obtain a context initialization parameter
     * (or attribute if the parameter is not defined).
     * <p>
     * <b><em>Note:</em></b>
     * The special behavior of allowing a context <em>attribute</em>
     * to be used instead of a context <em>parameter</em> is provided
     * to accommodate IBM WebSphere 3.5.2,
     * which allows attributes to be defined,
     * but does <em>not</em> allow context init. parameters to be defined.
     *
     * @param   sName the desired parameter (or attribute) name.
     *
     * @param   sDefault a default value to use if the parameter
     *          (or attribute) is not defined.
     *
     * @return  value of servlet initialization parameter
     *          (or attribute) <code>sName</code>.
     *          If <code>sName</code> is not defined as a parameter
     *          or attribute,
     *          returns <code>sDefault</code>.
     */
    protected final String getContextInitParameter(
        String sName,
        String sDefault
    ) throws ServletException {
        final String fName = "getContextInitParameter";

        ServletContext context = getServletContext();
        String sValue = context.getInitParameter(sName);
        if (sValue == null) {
            // Accommodate IBM WebSphere 3.5.2 by allowing String values
            // defined as context attributes to be treated as
            // context init. parameters.
            try {
                sValue = (String) context.getAttribute(sName);
            } catch (ClassCastException e) {
                throw new ServletException(
                        "Could not read context attribute [" +
                            sName +
                            "] as a String value",
                            e
                        );
            }
        }
        return (null != sValue) ? sValue : sDefault;
    }

    /**
     * Obtain a context initialization parameter
     * (or attribute if the parameter is not defined),
     * throwing an exception if the parameter (or attribute) is not defined.
     * <p>
     * <b><em>Note:</em></b>
     * The special behavior of allowing a context <em>attribute</em>
     * to be used instead of a context <em>parameter</em> is provided
     * to accommodate IBM WebSphere 3.5.2,
     * which allows attributes to be defined,
     * but does <em>not</em> allow context init. parameters to be defined.
     *
     * @param   sName the desired parameter (or attribute) name.
     *
     * @return  value of servlet initialization parameter
     *          (or attribute) <code>sName</code>.
     *
     * @exception   IllegalStateException if <code>sName</code> is not defined
     *              as a servlet initialization parameter.
     */
    protected final String getRequiredContextInitParameter(
        String sName
    ) throws ServletException, IllegalStateException {
        final String sValue = getContextInitParameter(sName, null);

        if (null == sValue) {
            throw new IllegalStateException(
                    "Context initialization parameter (or attribute) ["
                    + sName
                    + "] is undefined"
                    );
        }

        return sValue;
    }

    /**
     * Wrapper for PersistServer.beginTransaction() and perform logging.
     *
     * @param   fName the name of the driving method,
     *          for inclusion in log messages.
     */
    protected void beginTransaction(
        HttpServletRequest req,
        String fName
    ) throws ServletException {
        ILogger trcLogger = getTraceLogger(req);

        try {
            PersistServer.beginTransaction();
        } catch (CFiError e) {
            throw new ServletException("Cannot begin i-Series transaction", e);
        }

        if (trcLogger.isLogging())
            trcLogger.message(IRecordType.TYPE_INFO, this, fName, "began transaction");
    }

    /**
     * Wrapper for PersistServer.commitTransaction() and perform logging.
     *
     * @param   fName the name of the driving method,
     *          for inclusion in log messages.
     */
    protected void commitTransaction(
        HttpServletRequest req,
        String fName
    ) throws ServletException {
        ILogger trcLogger = getTraceLogger(req);

        try {
            PersistServer.commitTransaction();
        } catch (Exception e) {
            throw new ServletException("Cannot commit i-Series transaction", e);
        }

        if (trcLogger.isLogging())
            trcLogger.message(IRecordType.TYPE_INFO, this, fName, "committed transaction");
    }

    /**
     * Wrapper for PersistServer.rollbackTransaction().
     * Adds logging, try/catch, and tests that transaction is active.
     *
     * @param   fName the name of the driving method,
     *          for inclusion in log messages.
     */
    protected void rollbackTransaction(
        HttpServletRequest req,
        String fName
    ) throws ServletException {
        ILogger trcLogger = getTraceLogger(req);

        if (PersistServer.transactionIsActive()) {
            try {
                PersistServer.rollbackTransaction();

                if (trcLogger.isLogging()) {
                    trcLogger.message(
                        IRecordType.TYPE_INFO,
                        this,
                        fName,
                        "rolled back transaction");
                }
            } catch (Throwable t) {
                throw new ServletException(t.toString(), t);
            }
        }
    }

    /**
     * Activate i-Series engine and perform logging.
     *
     * @param   fName the name of the driving method,
     *          for inclusion in log messages.
     */
    protected void activateISeriesEngine(
        HttpServletRequest req,
        String fName
    ) throws ServletException {
        ILogger trcLogger = getTraceLogger(req);

        try {
            PersistServer.activate("Maxis");

            if (trcLogger.isLogging()) {
                trcLogger.message(
                        IRecordType.TYPE_INFO,
                        this,
                        fName,
                        "Called PersistServer.activate()");
            }
        } catch (com.checkfree.isolutions.utility.CFiError t) {
            throw new ServletException("Cannot activate i-Series engine", t);
        }

        if (trcLogger.isLogging())
            trcLogger.message(IRecordType.TYPE_INFO, this, fName, "Activated i-Series engine");
    }

    /**
     * Deactivate i-Series engine and perform logging.
     *
     * @param   fName the name of the driving method,
     *          for inclusion in log messages.
     */
    protected void deactivateISeriesEngine(
        HttpServletRequest req,
        String fName
    ) throws ServletException {
        ILogger trcLogger = getTraceLogger(req);

        PersistServer.deactivate();

        if (trcLogger.isLogging()) {
            trcLogger.message(
                    IRecordType.TYPE_INFO,
                    this,
                    fName,
                    "Called PersistServer.deactivate()");
        }
    }


    /**
     * Forwards the request to a parameterized destination.
     * Maps the parameter into a URL.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   urlParameter the symbolic name to be mapped to a specific URL.
     */
    public void forwardToMappedUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String urlParameter
    ) throws ServletException, java.io.IOException {
        forwardToMappedUrl(req, res, urlParameter, null);
    }

    /**
     * Forwards the request to a parameterized destination.
     * Maps the parameter into a URL, then appends the query parameters string.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   urlParameter the symbolic name to be mapped to a specific URL.
     *
     * @param   queryParameters a text string in the format
     *          "name1=value1&name2=value2" containing request query parameters
     *          to be appended to the mapped URL.
     *          A <b>null</b> value is treated as an empty string ("").
     *          If the query parameters string is <em>not</em> empty,
     *          this method prefixes the "?" character.
     */
    public void forwardToMappedUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String urlParameter,
        String queryParameters
    ) throws ServletException, java.io.IOException {
        final String fName = "forwardToMappedUrl";
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, this, fName, urlParameter);

        String sUrlMapped = getMappedUrl(urlParameter, req);

        if ((null != queryParameters) && (queryParameters.length() != 0))
            sUrlMapped += ("?" + queryParameters);

        forwardToUrl(req, res, sUrlMapped);

        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, this, fName, urlParameter);
    }

    /**
     * Forwards the request to URI.
     * Applies HttpServletResponse.encodeURL() to URL.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   url the complete URL that is the target of the forward.
     */
    public void forwardToUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String url
    ) throws ServletException, java.io.IOException {
        final String fName = "forwardToUrl";
        final Class theClass = EbppxServlet.class;
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, theClass, fName, url);

        RequestDispatcher disp = req.getRequestDispatcher(url);

        if (null == disp) {
            if (trcLogger.isLogging()) {
                trcLogger.message(
                        IRecordType.TYPE_INFO,
                        theClass,
                        fName,
                        "Attempting to forward request to /" + url);
            }

            disp = req.getRequestDispatcher(res.encodeURL("/" + url));

            if (null == disp)
                throw new ServletException("Cannot create RequestDispatcher for \"" + url + "\"");
        }

        disp.forward(req, res);

        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, theClass, fName);
    }

    /**
     * Redirects the request to URI.
     * Applies HttpServletResponse.encodeURL() URL.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   url the complete URL that is the target of the redirection.
     */
    public void redirectToUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String url
    ) throws ServletException, java.io.IOException {
        final Class theClass = EbppxServlet.class;
        final String fName = "redirectToUrl";
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, theClass, fName, url);

        res.sendRedirect(res.encodeURL(url));

        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, theClass, fName);
    }

    /**
     * Map a symbolic name to a specific relative URL string.
     * Attempt to resolve the symbolic <code>name</code>
     * as a request parameter,
     * a servlet initialization parameter,
     * a context initialization parameter,
     * or a context attribute (in that order).
     * <p>
     * <b><em>Note:</em></b>
     * The administrative console for IBM WebSphere 3.5.2 does not
     * allow for context initialization parameters to be configured;
     * context <em>attributes</em> are allowed as
     * a work-around to this issue.
     *
     * @param   name the symbolic name to be resolved into a URL.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @exception   ServletException <code>name</code> is undefined
     *              in all four namespaces.
     */
    protected final String getMappedUrl(
        String name,
        HttpServletRequest req
    ) throws ServletException {
        final String fName = "getMappedUrl";

        String sUrl = null;

        EbppxUrlManager urlManager = getUrlManager(req);

        if (null != (sUrl = urlManager.getRequestParameter(name, null))) {
            // do nothing, sUrl just got set
        } else if (null != (sUrl = getInitParameter(name))) {
            // do nothing, sUrl just got set
        } else {
            sUrl = getContextInitParameter(name, null);
        }
        if (sUrl == null) {
            throw new ServletException(
                "Could not locate URL mapping parameter [" + name + "]"
                );
        }

        return sUrl;
    }

    /**
     * Redirects the request to a parameterized destination.
     * Maps the parameter into a URL.
     * Applies HttpServletResponse.encodeURL() to URL.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   urlParameter the symbolic name to be mapped to a specific URL.
     */
    public void redirectToMappedUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String urlParameter
    ) throws ServletException, java.io.IOException {
        redirectToMappedUrl(req, res, urlParameter, null);
    }

    /**
     * Redirects the request to a parameterized destination.
     * Maps the parameter into a URL, then appends the query parameters string.
     * Applies HttpServletResponse.encodeURL() to URL.
     *
     * @param   req the request instance provided by the servlet engine.
     *
     * @param   res the response instance provided by the servlet engine.
     *
     * @param   urlParameter the symbolic name to be mapped to a specific URL.
     *
     * @param   queryParameters a text string in the format
     *          "name1=value1&name2=value2" containing request query parameters
     *          to be appended to the mapped URL.
     *          A <b>null</b> value is treated as an empty string ("").
     *          If the query parameters string is <em>not</em> empty,
     *          this method prefixes the "?" character.
     */
    public void redirectToMappedUrl(
        HttpServletRequest req,
        HttpServletResponse res,
        String urlParameter,
        String queryParameters
    ) throws ServletException, java.io.IOException {
        final String fName = "redirectToMappedUrl";
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, this, fName, urlParameter);

        String sUrlMapped = getMappedUrl(urlParameter, req);

        if ((null != queryParameters) && (queryParameters.length() != 0))
            sUrlMapped += ("?" + queryParameters);

        redirectToUrl(req, res, sUrlMapped);

        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, this, fName, urlParameter);
    }

    /**
     * Convenience method to fetch the UserHome from the i-Series API.
     *
     * @return  <code>UserHomeImpl.singleton()</code>
     */
    public UserHomeImpl getUserHome() {
        return UserHomeImpl.singleton();
    }

    /**
     * Convenience method to fetch the AccountHome from the i-Series API.
     *
     * @return  <code>AccountHomeImpl.singleton()</code>
     */
    public AccountHomeImpl getAccountHome() {
        return AccountHomeImpl.singleton();
    }

    /**
     * Convenience method to fetch the StatementHome from the i-Series API.
     *
     * @return  <code>StatementHomeImpl.singleton()</code>
     */
    public StatementHomeImpl getStatementHome() {
        return StatementHomeImpl.singleton();
    }
}
